package com.iot.ammeter.network

import com.iot.ammeter.model.parcelable.DeviceInfo
import com.iot.ammeter.model.parcelable.LastMonthInfo
import com.iot.ammeter.model.parcelable.UserInfo
import kotlinx.coroutines.async

object Repository {

    /**
     * 获取用户信息和设备信息，当用户信息中的 deviceId 为 null 时不继续获取设备信息
     * @param onSuccess 成功时调用，传入获取到的 userInfo 和 deviceInfo（可能为 null）
     */
    suspend fun getBaseInfo(
        token: String,
        onFailure: () -> Unit = {},
        onFinished: (Boolean) -> Unit = {},
        onSuccess: (UserInfo, DeviceInfo?, LastMonthInfo) -> Unit
    ) = NetworkHelper.withLogic(
        onFailure = onFailure,
        onFinished = onFinished,
        onRequest = {
            // 等待网络请求结束返回 UserInfo 对象
            val userInfo = NetworkHelper.getUserInfo(token)
            // 开启协程发起 LastMonthInfo 数据请求
            val lastMonthInfoAsync = async {
                NetworkHelper.getLastMonthInfo(userInfo.userId, userInfo.deviceId)
            }

            // 开启协程发起 DeviceInfo 数据请求，并等待请求完成
            val deviceInfo = userInfo.deviceId?.let {
                async {
                    NetworkHelper.getDeviceInfo(it)
                }
            }?.await()

            // 等待 LastMonthInfo 请求完成
            val lastMonthInfo = lastMonthInfoAsync.await()
            mapOf(
                UserInfo::class.java to userInfo,
                DeviceInfo::class.java to deviceInfo,
                LastMonthInfo::class.java to lastMonthInfo
            )
        },
        onSuccess = {
            onSuccess(
                it[UserInfo::class.java] as UserInfo,
                it[DeviceInfo::class.java] as DeviceInfo?,
                it[LastMonthInfo::class.java] as LastMonthInfo
            )
        }
    )

     suspend fun login(
        email: String, password: String,
        onFailure: () -> Unit = {},
        onFinished: (Boolean) -> Unit = {},
        onSuccess: (token: String) -> Unit
    ) = NetworkHelper.withLogic(
        onRequest = {
            NetworkHelper.tryLogin(email, password)
        },
        onSuccess = {
            onSuccess(it)
        },
        onFailure = onFailure,
        onFinished = onFinished
    )

    suspend fun register(
        email: String, password: String, mailCode: String,
        onFailure: () -> Unit = {},
        onFinished: (Boolean) -> Unit = {},
        onSuccess: (token: String) -> Unit
    ) = NetworkHelper.withLogic(
        onRequest = {
            NetworkHelper.toRegister(email, password, mailCode)
        },
        onSuccess = {
            onSuccess(it)
        },
        onFailure = onFailure,
        onFinished = onFinished
    )
}
